#include <Windows.h>
#include <iostream>
#include <cassert>
#include <fstream>
#include <string>
#include <sstream>


#include <main/GameLoop.h>
#include "ConstantManager.h"
#include <main/Globals.h>

// Accessors
int ConstantManager::getInt(INT_VARS val) {
	return intVec[val];
}

float ConstantManager::getFloat(FLOAT_VARS val) {
	return floatVec[val];
}

std::string ConstantManager::getString(STRING_VARS val) {
	return stringVec[val];
}

// Get notifications about folder changes on PATH
ConstantManager::ConstantManager() {
	#ifdef IS_GAME_IN_DEVELOPMENT
		
	hDir = CreateFile(
	PATH_TO_MONITOR,
	FILE_LIST_DIRECTORY,
	FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
	NULL, 
	OPEN_EXISTING, 
	FILE_FLAG_BACKUP_SEMANTICS, 
	NULL
	);

	if( hDir == INVALID_HANDLE_VALUE )
	{
		DWORD dwError = GetLastError();
		if(dwError == 3) {
			std::cout << "You must create the folder path to monitor before starting the app" << std::endl;
		} else {
			//assert(false);
		}
	}

	parseFile();

	// Create thread to poll for changes
	threadHandle = CreateThread(NULL, 0, &ConstantManager::threadProc, this, 0, 0); 

	#else 
	// When releasing the game just add the vars here hardcoded to the vectors 
	intVec.push_back(5);
	#endif

}

DWORD WINAPI ConstantManager::threadProc(LPVOID lpParam) {
	reinterpret_cast<ConstantManager*>(lpParam)->thread();
	return 0;
}

ConstantManager::~ConstantManager() {
	CloseHandle(hDir);
	TerminateThread(threadHandle, 0);
	CloseHandle(threadHandle);
}

void ConstantManager::thread() {
	while(true) {
		FILE_NOTIFY_INFORMATION strFileNotifyInfo[1024];
		DWORD dwBytesReturned = 0;   

		if( ReadDirectoryChangesW ( hDir, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE, &dwBytesReturned, NULL, NULL) != 0) {
			std::cout << "File Modified: " << std::endl;
			parseFile();
		}
	}
}
	
void ConstantManager::parseFile() {
	intVec.clear();
	floatVec.clear();
	stringVec.clear();

	std::string filename = std::string(PATH_TO_MONITOR) + std::string("\\config.txt");
	std::ifstream configFile(filename.c_str());
	if(configFile.good()) {
		for (std::string line; std::getline(configFile, line); ) {
			// Parse CSV TYPE, VALUE
			std::stringstream  lineStream(line);
			std::string type;
			std::getline(lineStream, type, ',');

			std::string value;
			std::getline(lineStream, value, ',');

			if(type == "int") {
				intVec.push_back(atoi(value.c_str()));
			} else if (type == "float") {
				floatVec.push_back(atof(value.c_str()));
			} else if (type == "string") {
				stringVec.push_back(value);
			} else {
				assert(false);
			}
		}
	} else {
		std::cout << "Could not find the config file. READ ConstantManager class" << std::endl;
	}	
}
